package com.yunbai.yunbaigrowup.utils;

import com.baidu.nplatform.comapi.basestruct.GeoPoint;

import android.graphics.Rect;
import android.util.Log;

public class AreaLine {

	/**
	 * 判断点与多边形的关系
	 * 
	 * @param pos
	 *            输入的点
	 * @param posArray
	 *            输入的多边形顶点坐标数组
	 * @return 判断结果, -1表示点在多边形外，1表示点在多边形内，0表示点在多边形的边上
	 */
	public static int isPointInPolygon(GeoPoint pos, GeoPoint[] posArray) {
		// int ret = 0;
		Rect maxRect = getMaxRect(posArray);
		// 若点不在多边形的外接矩形中，则点不在多边形内
		if (!maxRect.contains((int) pos.getLatitudeE6(),
				(int) pos.getLongitudeE6())) {
			Log.e("m_tag", "点不在多边形的外接矩形中");
			return -1;
		}

		// 计算该点左方向的水平射线与多边形各边交点的个数
		int count = 0;

		for (int i = 0; i < posArray.length; i++) {
			int check = 0;

			if (i == posArray.length - 1) {
				check = isIntersersectant(pos, posArray[i], posArray[0]);
			} else {
				check = isIntersersectant(pos, posArray[i], posArray[i + 1]);
			}

			if (check == 0) {
				// 如果点在多边形的某条边上，则判定为点在多边形边上
				return 0;
			} else if (check == 1) {
				count++;
			}
		}

		// Log.d(TAG, "count = " + count);

		if (count % 2 == 0) {
			// 如果交点为偶数个，则点在多边形外
			return -1;
		} else {
			// 点在多边形内
			return 1;
		}
	}

	/**
	 * 判断射线与线段的关系
	 * 
	 * @param posPoint
	 *            射线的起点
	 * @param posLine1
	 *            线段的端点1
	 * @param posLine2
	 *            线段的端点2
	 * @return 判断结果, -1表示不相交，1表示相交，0表示射线起点在线段上
	 */
	private static int isIntersersectant(GeoPoint posPoint, GeoPoint posLine1,
			GeoPoint posLine2) {
		// int ret = 0;

		// 计算线段端点的最小和最大坐标值
		double minX, maxX, minY, maxY;

		if (posLine1.getLatitudeE6() > posLine2.getLatitudeE6()) {
			minX = posLine2.getLatitudeE6();
			maxX = posLine1.getLatitudeE6();
		} else {
			minX = posLine1.getLatitudeE6();
			maxX = posLine2.getLongitudeE6();
		}

		if (posLine1.getLongitudeE6() > posLine2.getLongitudeE6()) {
			minY = posLine2.getLongitudeE6();
			maxY = posLine1.getLongitudeE6();
		} else {
			minY = posLine1.getLongitudeE6();
			maxY = posLine2.getLongitudeE6();
		}

		// 简单判断那些一定不会相交的特殊情况
		if (posPoint.getLongitudeE6() < minY
				|| posPoint.getLongitudeE6() > maxY
				|| posPoint.getLongitudeE6() < minX) {
			return -1;
		}

		// 坐标点取整时统一按向下取整处理

		// 如果是水平线段，则点在线段上返回0，否则返回－1
		if ((int) minY == (int) maxY) {
			if (posPoint.getLatitudeE6() > minX
					&& posPoint.getLatitudeE6() < maxX) {
				return 0;
			} else {
				return -1;
			}
		}

		// 计算射线所在直线与线段所在直线的交点的横坐标
		double x0 = posLine1.getLatitudeE6()
				+ (posPoint.getLongitudeE6() - posLine1.getLongitudeE6())
				* (posLine2.getLatitudeE6() - posLine1.getLatitudeE6())
				/ (posLine2.getLongitudeE6() - posLine1.getLongitudeE6());

		if ((int) x0 == (int) posPoint.getLatitudeE6()) {
			// 射线起点与交点是同一点（取整），说明射线起点在线段上
			return 0;
		} else if (x0 > posPoint.getLatitudeE6()) {
			// 射线起点在交点的左侧，说明射线与线段不相交
			return -1;
		} else if ((int) maxY == (int) posPoint.getLongitudeE6()) {
			// 射线穿过了线段的下端点，则认为不相交
			return -1;
		}

		return 1;
	}

	/**
	 * 获取多边形的最小外接矩形
	 * 
	 * @param posArray
	 *            多边形的顶点坐标数组
	 * @return 最小外接矩形
	 */
	private static Rect getMaxRect(GeoPoint[] posArray) {
		Rect rect;
		double left, right, top, bottom;

		left = right = (int) posArray[0].getLatitudeE6();
		top = bottom = (int) posArray[0].getLongitudeE6();

		for (int i = 1; i < posArray.length; i++) {
			if (posArray[i].getLatitudeE6() < left) {
				left = posArray[i].getLatitudeE6();
			}

			if (posArray[i].getLatitudeE6() > right) {
				right = posArray[i].getLatitudeE6();
			}

			if (posArray[i].getLongitudeE6() < top) {
				top = posArray[i].getLongitudeE6();
			}

			if (posArray[i].getLongitudeE6() > bottom) {
				bottom = posArray[i].getLongitudeE6();
			}
		}

		rect = new Rect((int) left, (int) top, (int) right, (int) bottom);
		return rect;
	}

}
